package nes

import "errors"

var (
	NES_TAG           = []byte{0x4E, 0x45, 0x53, 0x1A}
	PRG_ROM_PAGE_SIZE = 16384
	CHR_ROM_PAGE_SIZE = 8192
)

const MirroringVertical = uint8(0)
const MirroringHorizontal = uint8(1)
const MirroringFourScreen = uint8(2)

type Rom struct {
	PrgRom          []byte
	ChrRom          []byte
	Mapper          byte
	ScreenMirroring byte
}

func NewRom(raw []byte) (*Rom, error) {

	if string(raw[0:4]) != string(NES_TAG) {
		return nil, errors.New("File is not in iNES file format")
	}

	mapper := (raw[7] & 0b1111_0000) | (raw[6] >> 4)

	inesVer := (raw[7] >> 2) & 0b11
	if inesVer != 0 {
		return nil, errors.New("NES2.0 format is not supported")
	}

	fourScreen := raw[6]&0b1000 != 0
	verticalMirroring := raw[6]&0b1 != 0
	var screenMirroring uint8
	switch {
	case fourScreen:
		screenMirroring = MirroringFourScreen
	case verticalMirroring:
		screenMirroring = MirroringVertical
	default:
		screenMirroring = MirroringHorizontal
	}

	prgRomSize := int(raw[4]) * PRG_ROM_PAGE_SIZE
	chrRomSize := int(raw[5]) * CHR_ROM_PAGE_SIZE

	skipTrainer := raw[6]&0b100 != 0

	prgRomStart := 16
	if skipTrainer {
		prgRomStart += 512
	}
	chrRomStart := prgRomStart + prgRomSize

	return &Rom{
		PrgRom:          raw[prgRomStart : prgRomStart+prgRomSize],
		ChrRom:          raw[chrRomStart : chrRomStart+chrRomSize],
		Mapper:          mapper,
		ScreenMirroring: screenMirroring,
	}, nil
}
